import AppDataSource from "@/common/database";
import { encrypt } from "@/common/utils/password";
import { Manager } from "@/models/Manager";
import { Hono } from "hono";
import { HTTPException } from "hono/http-exception";
import { z } from "zod";
import * as argon2 from "argon2";
import { Role } from "@/models/Role";
import { Store } from "@/models/Store";

const adminRoute = new Hono();

const addSchema = z.object({
  name: z.string(),
  username: z.string(),
  roleId: z.nullable(z.coerce.number()),
  storeId: z.nullable(z.coerce.number()),
});

const editSchema = z.object({
  id: z.coerce.number(),
  name: z.string(),
  username: z.string(),
  roleId: z.nullable(z.coerce.number()).optional(),
  storeId: z.nullable(z.coerce.number()).optional(),
});

adminRoute.get("/list", async (c) => {
  let [list, count] = await AppDataSource.createQueryBuilder()
    .select("manager")
    .from(Manager, "manager")
    .leftJoinAndSelect("manager.role", "role")
    .leftJoinAndSelect("manager.store", "store")
    .getManyAndCount();

  return c.json({ message: "hello", data: { list, count } });
});

adminRoute.get("/info", async (c) => {
  const payload = c.get("jwtPayload");
  let id = payload.sub;

  let manager = await Manager.findOne({
    where: { id },
    relations: {
      role: {
        permissions: true,
      },
      store: true,
    },
  });

  return c.json({ code: 200, message: "success", data: manager });
});

adminRoute.post("/add", async (c) => {
  let body = await c.req.parseBody();
  let result = addSchema.safeParse(body);

  if (!result.success) {
    let message = result.error.issues
      .map((item) => item.path.join(",") + item.message)
      .join(",");
    throw new HTTPException(400, { message });
  }

  // 查询是否存在
  let num = await Manager.countBy({ username: result.data.username });

  if (num > 0) {
    throw new HTTPException(400, { message: "用户名已存在" });
  }

  let hash = await argon2.hash(process.env.DEFAULT_PASSWORD);

  let manager = Manager.create();
  manager.name = result.data.name;
  manager.username = result.data.username;
  manager.password = hash;

  if (result.data.roleId) {
    let role = await AppDataSource.createQueryBuilder()
      .select("role")
      .from(Role, "role")
      .where("role.id = :id", { id: result.data.roleId })
      .getOne();

    if (!role) {
      throw new HTTPException(400, { message: "角色不存在" });
    }

    manager.role = role;
  }

  if (result.data.storeId) {
    let store = await AppDataSource.createQueryBuilder()
      .select("store")
      .from(Store, "store")
      .where("store.id = :id", { id: result.data.storeId })
      .getOne();

    if (!store) {
      throw new HTTPException(400, { message: "店铺不存在" });
    }

    manager.store = store;
  }

  await Manager.save(manager);

  return c.json({ code: 200, message: "添加成功", data: manager });
});

adminRoute.post("/edit", async (c) => {
  let body = await c.req.parseBody();
  let result = editSchema.safeParse(body);

  if (!result.success) {
    let message = result.error.issues
      .map((item) => item.path.join(",") + item.message)
      .join(",");
    throw new HTTPException(400, { message });
  }

  let manager = await Manager.findOneBy({ id: +result.data.id });

  if (!manager) {
    throw new HTTPException(404, { message: "用户不存在" });
  }

  // let hash = await argon2.hash(result.data.password);

  manager.name = result.data.name;
  manager.username = result.data.username;
  // manager.password = hash;

  if (result.data.roleId) {
    let role = await AppDataSource.createQueryBuilder()
      .select("role")
      .from(Role, "role")
      .where("role.id = :id", { id: result.data.roleId })
      .getOne();

    if (!role) {
      throw new HTTPException(400, { message: "角色不存在" });
    }

    manager.role = role;
  }

  if (result.data.storeId) {
    let store = await AppDataSource.createQueryBuilder()
      .select("store")
      .from(Store, "store")
      .where("store.id = :id", { id: result.data.storeId })
      .getOne();

    if (!store) {
      throw new HTTPException(400, { message: "店铺不存在" });
    }

    manager.store = store;
  }

  await manager.save();
  return c.json({ code: 200, message: "添加成功", data: manager });
});

adminRoute.get("/permissions", async (c) => {
  const payload = c.get("jwtPayload");
  let id = payload.sub;

  let manager = await Manager.findOne({
    where: { id },
    relations: {
      role: {
        permissions: true,
      },
    },
  });

  if (!manager) {
    throw new HTTPException(404, { message: "用户不存在" });
  }

  if (!manager.role) {
    throw new HTTPException(404, { message: "用户未分配角色" });
  }

  if (!manager.role.permissions) {
    throw new HTTPException(404, { message: "用户未分配权限" });
  }

  let permissions = manager.role.permissions;

  return c.json({ code: 200, message: "获取成功", data: permissions });
});

export default adminRoute;
